package com.um.jdy.platform.order.manager;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.um.jdy.baofu.api.BaofuPayService;
import com.um.jdy.common.baofu.entity.po.BaofuRefund;
import com.um.jdy.common.baofu.service.BaofuRefundService;
import com.um.jdy.common.charge.code.OrderCode;
import com.um.jdy.common.charge.entity.po.DepositOrder;
import com.um.jdy.common.charge.entity.po.Order;
import com.um.jdy.common.charge.enums.OrderEnum;
import com.um.jdy.common.charge.service.DepositOrderService;
import com.um.jdy.common.charge.service.OrderService;
import com.um.jdy.common.finance.entity.po.PlatformBill;
import com.um.jdy.common.finance.entity.po.UserBill;
import com.um.jdy.common.finance.enums.FinancialEnum;
import com.um.jdy.common.finance.service.PlatformBillService;
import com.um.jdy.common.finance.service.UserBillService;
import com.um.jdy.common.member.enums.PayEnum;
import com.um.jdy.common.member.service.MemberUserService;
import com.um.jdy.common.commons.manager.WxManager;
import com.um.jdy.platform.order.entity.dto.RefundDTO;
import com.um.jdy.platform.order.entity.vo.DepositOrderItemVO;
import com.um.jdy.platform.user.service.SessionUserService;
import com.um.springboot.starter.entity.Page;
import com.um.springboot.starter.exception.ServiceException;
import com.um.springboot.starter.orm.entity.Response;
import com.um.springboot.starter.orm.manager.BaseManager;
import com.um.springboot.starter.orm.params.PageParams;
import com.um.springboot.starter.utils.OrderUtil;
import com.um.springboot.starter.utils.PayUtil;
import com.um.springboot.starter.utils.StringUtil;
import com.um.weixin.pay.service.WxBasePayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Component
@Slf4j
public class DepositOrderManager extends BaseManager<DepositOrderService> {

    @Autowired
    SessionUserService sessionUserService;

    @Autowired
    UserBillService userBillService;

    @Autowired
    PlatformBillService platformBillService;

    @Autowired
    OrderService orderService;
    @Autowired
    MemberUserService memberUserService;

    @Autowired
    WxManager wxManager;

    @Autowired
    WxBasePayService wxPayService;
    @Autowired
    BaofuPayService baofuPayService;

    @Autowired
    BaofuRefundService baofuRefundService;

    /**
     * 分页查询订单
     *
     * @param pageParams
     * @return
     */
    public Response<Page<DepositOrderItemVO>> page(PageParams pageParams) {
        Page<DepositOrderItemVO> page = new Page<>();
        page.setPageNo(pageParams.getPageNo());
        page.setPageSize(pageParams.getPageSize());
        pageParams.getCondition().put("o.com_id", getComId());
        page = service.getCMSViewModelPageBySqlName(page, "get_deposit_order_page", "get_deposit_order_count",
                DepositOrderItemVO.class, pageParams.getProperties(), pageParams.getValues(),
                pageParams.getRangeEntitys(), pageParams.getOrderNames(), pageParams.getSortOns());
        return Response.success(page);
    }

    @Transactional
    public Response refund(RefundDTO refundDTO) throws Exception {

        DepositOrder depositOrder = service.getEntity(refundDTO.getChargeDepositOrderId());
        if(depositOrder == null){
            throw new ServiceException(OrderCode.NoDepositOrder);
        }


        if(StringUtil.getTrim(depositOrder.getPayStatus()).equals(PayEnum.Status.UnPayed.name())) {
            return Response.failed(OrderCode.UnPayNotSupportReturn);
        }

        //订单未完成或未支付，不能退款
        Order order = orderService.getEntity(depositOrder.getChargeOrderId());
        if(order != null && (!order.getStatus().equals(OrderEnum.Status.Completed.name()) || !order.getPayStatus().equals(PayEnum.Status.Payed.name()))){
            return Response.failed(OrderCode.UnRefundForOrderUncomplete);
        }

        String outTradeNo = StringUtil.getTrim(depositOrder.getOutTradeNo());
        String orderNo = StringUtil.getTrim(depositOrder.getOrderNo());
        boolean result = true;
        int returnAmount = depositOrder.getAmount() - depositOrder.getPayOrderAmount();
        depositOrder.setReturnAmount(returnAmount);//记录退款金额

        String returnMsg = "";
        // TODO: 2023-06-13  支付待接入
        if (PayUtil.isProd()) {
            if (PayEnum.PayWay.Wxpay.name().equals(depositOrder.getPayWay())) {//退回微信零钱或银行卡
                /** TODO 修改宝付支付
                try {
                    wxManager.getPayService(depositOrder.getComId());
                    int totalFee = StringUtil.toInt(depositOrder.getAmount());
                    wxPayService.refundOrder(outTradeNo, OrderUtil.getWxOrderNo(), totalFee, returnAmount);

                    depositOrder.setReturnStatus(OrderEnum.DepositReturnStatus.Yes.name());//退款成功
                    depositOrder.setReturnTime(new Date());
                    service.update(depositOrder);

                } catch (WxPayException ex) {
                    depositOrder.setReturnStatus(OrderEnum.DepositReturnStatus.No.name());//退款失败
                    depositOrder.setReturnTime(new Date());
                    service.update(depositOrder);

                    returnMsg = ex.getCustomErrorMsg();
                    result = false;
                    log.error(StrUtil.format("押金订单{}微信提现异常", orderNo), ex);
                }*/
                try {
                    String type ="deposit";
                    String refundNo = OrderUtil.getWxOrderNo();
                    int totalFee = StringUtil.toInt(depositOrder.getAmount());
                    baofuPayService.refundOrder(outTradeNo, OrderUtil.getWxOrderNo(), totalFee, returnAmount,type,order.getComId());

//                    depositOrder.setReturnStatus(OrderEnum.DepositReturnStatus.Yes.name());//退款成功
//                    depositOrder.setReturnTime(new Date());
                    service.update(depositOrder);
                    BaofuRefund baofuRefund = new BaofuRefund();
                    baofuRefund.setComId(order.getComId());
                    baofuRefund.setRefundAmount(returnAmount);
                    baofuRefund.setOutRefundNo(refundNo);
                    baofuRefund.setRefundState("REFUND");
                    baofuRefund.setOutTradeNo(outTradeNo);
                    baofuRefund.setType(type);
                    baofuRefundService.addRefund(baofuRefund);
                    return Response.success("押金退款成功！");

                } catch (ServiceException ex) {
                    depositOrder.setReturnStatus(OrderEnum.DepositReturnStatus.No.name());//退款失败
                    depositOrder.setReturnTime(new Date());
                    service.update(depositOrder);

                    returnMsg = ex.getMsg();
                    result = false;
                    log.error(StrUtil.format("押金订单{}微信提现异常", orderNo), ex);
                }
            } else if (PayEnum.PayWay.Alipay.name().equals(depositOrder.getPayWay())) {//退回支付宝
                try {
                    //Map refundResult = payService.refund(outTradeNo, payUtil.toDoubleAmount(totalFee));
                    depositOrder.setReturnStatus(OrderEnum.DepositReturnStatus.Yes.name());//退款成功
                    depositOrder.setReturnTime(new Date());
                    service.update(depositOrder);
                    //log.info("押金订单{}支付宝原路退款：{}", orderNo, JSONObject.toJSONString(refundResult));
                } catch (Exception e) {
                    depositOrder.setReturnStatus(OrderEnum.DepositReturnStatus.No.name());//退款失败
                    depositOrder.setReturnTime(new Date());
                    service.update(depositOrder);

                    returnMsg = "";//TODO
                    result = false;
                    log.error(StrUtil.format("" +
                            "refundSuccess = false;押金订单{}支付宝提现异常", orderNo), e);
                }
            }
        }

        if (result) {

            //更新提现状态
            depositOrder.setReturnStatus(OrderEnum.DepositReturnStatus.Yes.name());
            depositOrder.setReturnTime(new Date());
            service.update(depositOrder);


            //插入用户账单流水：押金提现
            UserBill userBill = new UserBill();
            userBill.setMemberUserId(depositOrder.getMemberUserId());
            userBill.setNo(OrderUtil.getOrderNo());
            userBill.setOutTradeNo(outTradeNo);
            userBill.setOrderNo(orderNo);
            userBill.setAmount(returnAmount);
            userBill.setType(FinancialEnum.IncomeOrExpend.Income.name());//收入支出类型：0-收入，1-支出
            userBill.setEvent(FinancialEnum.UserBillEvent.DepositCashout.name());
            userBill.setStatus(FinancialEnum.BillStatus.Effective.name());//账单状态：0未生效|1已生效|2已失效
            userBill.setCreateTime(DateUtil.date());
            userBillService.save(userBill);

            //插入平台账单流水：押金提现
            PlatformBill platformBill = new PlatformBill();
            platformBill.setNo(OrderUtil.getOrderNo());
            platformBill.setOutTradeNo(outTradeNo);
            platformBill.setOrderNo(orderNo);
            platformBill.setAmount(returnAmount);
            platformBill.setType(FinancialEnum.IncomeOrExpend.Expend.name());//收入支出类型：0-收入，1-支出
            platformBill.setEvent(FinancialEnum.PlatformBillEvent.DepositCashout.name());
            platformBill.setStatus(FinancialEnum.BillStatus.Effective.name());//账单状态：0未生效|1已生效|2已失效
            platformBill.setCreateTime(DateUtil.date());
            platformBillService.save(platformBill);

            return Response.success("押金退款成功！");
        }

        return Response.failed("押金退款失败:"+returnMsg);
    }
}
